﻿using System;
using System.IO;
using System.Runtime.Caching;
using System.Runtime.Serialization.Formatters.Binary;

namespace SoldiHive.Core.Cache
{
	public class Cache : ICache
	{
		private ICacheConfiguration configuration;
		private FileCache cache;

		public bool Enabled
		{
			get
			{
				return this.configuration.Enabled;
			}
		}

		public Cache(ICacheConfiguration configuration)
		{
			this.configuration = configuration;

			var cacheRoot = this.configuration.RootDirectory;
			var customObjectBinder = new CustomObjectBinder();

			this.cache = new FileCache(cacheRoot, customObjectBinder);
		}

		public string Key(params object[] values)
		{
			var cacheKey = string.Join("-", values);

			return cacheKey;
		}

		public bool Has(string cacheKey)
		{
			var cached = this.cache.Contains(cacheKey);

			return cached;
		}

		public T Get<T>(string cacheKey)
		{
			var fromCache = this.cache[cacheKey];

			if (fromCache == null && typeof(T).IsValueType)
			{
				throw new Exception(cacheKey);
			}

			return (T)fromCache;
		}

		public void Put(string cacheKey, object value)
		{
			var cacheLifeSpanDays = this.configuration.DefaultCacheLifeSpanDays;

			this.Put(cacheKey, value, cacheLifeSpanDays);
		}

		public void Put(string cacheKey, object value, int cacheLifeSpanDays)
		{
			var cacheLifeSpan = DateTimeOffset.Now.AddDays(cacheLifeSpanDays);

			this.cache.AddOrGetExisting(cacheKey, value, cacheLifeSpan);
		}
	}
}
